47 top_out = rotation_matrix * top_in;
48 bottom_out = -displacement.
cross(top_out) + rotation_matrix * bottom_in;
56 void InverseSpatialTransform(
const btMatrix3x3 &rotation_matrix,
63 top_out = rotation_matrix.
transpose() * top_in;
64 bottom_out = rotation_matrix.
transpose() * (bottom_in + displacement.
cross(top_in));
72 return a_bottom.
dot(b_top) + a_top.
dot(b_bottom);
75 void SpatialCrossProduct(
const btVector3 &a_top,
82 top_out = a_top.
cross(b_top);
83 bottom_out = a_bottom.
cross(b_top) + a_top.
cross(b_bottom);
159 const btVector3 &parentComToThisPivotOffset,
160 const btVector3 &thisPivotToThisComOffset,
bool )
163 m_links[i].m_inertiaLocal = inertia;
165 m_links[i].setAxisTop(0, 0., 0., 0.);
167 m_links[i].m_zeroRotParentToThis = rotParentToThis;
168 m_links[i].m_dVector = thisPivotToThisComOffset;
169 m_links[i].m_eVector = parentComToThisPivotOffset;
177 m_links[i].updateCacheMultiDof();
188 const btVector3 &parentComToThisPivotOffset,
189 const btVector3 &thisPivotToThisComOffset,
190 bool disableParentCollision)
196 m_links[i].m_inertiaLocal = inertia;
198 m_links[i].m_zeroRotParentToThis = rotParentToThis;
199 m_links[i].setAxisTop(0, 0., 0., 0.);
200 m_links[i].setAxisBottom(0, jointAxis);
201 m_links[i].m_eVector = parentComToThisPivotOffset;
202 m_links[i].m_dVector = thisPivotToThisComOffset;
203 m_links[i].m_cachedRotParentToThis = rotParentToThis;
208 m_links[i].m_jointPos[0] = 0.f;
209 m_links[i].m_jointTorque[0] = 0.f;
211 if (disableParentCollision)
215 m_links[i].updateCacheMultiDof();
226 const btVector3 &parentComToThisPivotOffset,
227 const btVector3 &thisPivotToThisComOffset,
228 bool disableParentCollision)
234 m_links[i].m_inertiaLocal = inertia;
236 m_links[i].m_zeroRotParentToThis = rotParentToThis;
237 m_links[i].setAxisTop(0, jointAxis);
238 m_links[i].setAxisBottom(0, jointAxis.
cross(thisPivotToThisComOffset));
239 m_links[i].m_dVector = thisPivotToThisComOffset;
240 m_links[i].m_eVector = parentComToThisPivotOffset;
245 m_links[i].m_jointPos[0] = 0.f;
246 m_links[i].m_jointTorque[0] = 0.f;
248 if (disableParentCollision)
251 m_links[i].updateCacheMultiDof();
261 const btVector3 &parentComToThisPivotOffset,
262 const btVector3 &thisPivotToThisComOffset,
263 bool disableParentCollision)
269 m_links[i].m_inertiaLocal = inertia;
271 m_links[i].m_zeroRotParentToThis = rotParentToThis;
272 m_links[i].m_dVector = thisPivotToThisComOffset;
273 m_links[i].m_eVector = parentComToThisPivotOffset;
278 m_links[i].setAxisTop(0, 1.f, 0.f, 0.f);
279 m_links[i].setAxisTop(1, 0.f, 1.f, 0.f);
280 m_links[i].setAxisTop(2, 0.f, 0.f, 1.f);
281 m_links[i].setAxisBottom(0,
m_links[i].getAxisTop(0).cross(thisPivotToThisComOffset));
282 m_links[i].setAxisBottom(1,
m_links[i].getAxisTop(1).cross(thisPivotToThisComOffset));
283 m_links[i].setAxisBottom(2,
m_links[i].getAxisTop(2).cross(thisPivotToThisComOffset));
285 m_links[i].m_jointPos[3] = 1.f;
288 if (disableParentCollision)
291 m_links[i].updateCacheMultiDof();
302 const btVector3 &parentComToThisComOffset,
303 bool disableParentCollision)
309 m_links[i].m_inertiaLocal = inertia;
311 m_links[i].m_zeroRotParentToThis = rotParentToThis;
312 m_links[i].m_dVector.setZero();
313 m_links[i].m_eVector = parentComToThisComOffset;
316 btVector3 vecNonParallelToRotAxis(1, 0, 0);
317 if (rotationAxis.
normalized().
dot(vecNonParallelToRotAxis) > 0.999)
318 vecNonParallelToRotAxis.
setValue(0, 1, 0);
325 m_links[i].setAxisTop(0, n[0], n[1], n[2]);
326 m_links[i].setAxisTop(1, 0, 0, 0);
327 m_links[i].setAxisTop(2, 0, 0, 0);
328 m_links[i].setAxisBottom(0, 0, 0, 0);
330 m_links[i].setAxisBottom(1, cr[0], cr[1], cr[2]);
332 m_links[i].setAxisBottom(2, cr[0], cr[1], cr[2]);
336 if (disableParentCollision)
339 m_links[i].updateCacheMultiDof();
343 m_links[i].setAxisBottom(1,
m_links[i].getAxisBottom(1).normalized());
344 m_links[i].setAxisBottom(2,
m_links[i].getAxisBottom(2).normalized());
365 return m_links[link_num].m_parent;
375 return m_links[i].m_inertiaLocal;
380 return m_links[i].m_jointPos[0];
390 return &
m_links[i].m_jointPos[0];
400 return &
m_links[i].m_jointPos[0];
411 m_links[i].updateCacheMultiDof();
417 for (
int pos = 0; pos <
m_links[i].m_posVarCount; ++pos)
420 m_links[i].updateCacheMultiDof();
425 for (
int pos = 0; pos <
m_links[i].m_posVarCount; ++pos)
428 m_links[i].updateCacheMultiDof();
440 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
446 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
452 return m_links[i].m_cachedRVector;
457 return m_links[i].m_cachedRotParentToThis;
462 return m_links[i].m_cachedRVector_interpolate;
467 return m_links[i].m_cachedRotParentToThis_interpolate;
474 if ((i < -1) || (i >=
m_links.size()))
499 if ((i < -1) || (i >=
m_links.size()))
520 if ((i < -1) || (i >=
m_links.size()))
539 if ((i < -1) || (i >=
m_links.size()))
560 result.
setValue(frameInWorld0[0], frameInWorld1[0], frameInWorld2[0], frameInWorld0[1], frameInWorld1[1], frameInWorld2[1], frameInWorld0[2], frameInWorld1[2], frameInWorld2[2]);
572 for (
int i = 0; i < num_links; ++i)
579 omega[parent + 1], vel[parent + 1],
580 omega[i + 1], vel[i + 1]);
584 for (
int dof = 0; dof < link.
m_dofCount; ++dof)
586 omega[i + 1] += jointVel[dof] * link.
getAxisTop(dof);
600 m_links[i].m_appliedConstraintForce.setValue(0, 0, 0);
601 m_links[i].m_appliedConstraintTorque.setValue(0, 0, 0);
611 m_links[i].m_appliedForce.setValue(0, 0, 0);
612 m_links[i].m_appliedTorque.setValue(0, 0, 0);
626 m_links[i].m_appliedForce += f;
631 m_links[i].m_appliedTorque += t;
636 m_links[i].m_appliedConstraintForce += f;
641 m_links[i].m_appliedConstraintTorque += t;
646 m_links[i].m_jointTorque[0] += Q;
651 m_links[i].m_jointTorque[dof] += Q;
656 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
657 m_links[i].m_jointTorque[dof] = Q[dof];
662 return m_links[i].m_appliedForce;
667 return m_links[i].m_appliedTorque;
672 return m_links[i].m_jointTorque[0];
677 return &
m_links[i].m_jointTorque[0];
720 row1[0], row1[1], row1[2],
721 row2[0], row2[1], row2[2]);
725#define vecMulVecTranspose(v0, v1Transposed) outerProduct(v0, v1Transposed)
732 bool isConstraintPass,
733 bool jointFeedbackInWorldSpace,
734 bool jointFeedbackInJointFrame)
767 scratch_v.
resize(8 * num_links + 6);
768 scratch_m.
resize(4 * num_links + 4);
776 v_ptr += num_links * 2 + 2;
780 v_ptr += num_links * 2 + 2;
784 v_ptr += num_links * 2;
797 v_ptr += num_links * 2 + 2;
827 spatVel[0].
setVector(rot_from_parent[0] * base_omega, rot_from_parent[0] * base_vel);
838 zeroAccSpatFrc[0].
setVector(-(rot_from_parent[0] * baseTorque), -(rot_from_parent[0] * baseForce));
841 const btScalar linDampMult = 1., angDampMult = 1.;
842 zeroAccSpatFrc[0].
addVector(angDampMult *
m_baseInertia * spatVel[0].getAngular() * (DAMPING_K1_ANGULAR + DAMPING_K2_ANGULAR * spatVel[0].getAngular().safeNorm()),
843 linDampMult *
m_baseMass * spatVel[0].getLinear() * (DAMPING_K1_LINEAR + DAMPING_K2_LINEAR * spatVel[0].getLinear().safeNorm()));
850 zeroAccSpatFrc[0].
addLinear(
m_baseMass * spatVel[0].getAngular().cross(spatVel[0].getLinear()));
864 rot_from_world[0] = rot_from_parent[0];
867 for (
int i = 0; i < num_links; ++i)
869 const int parent =
m_links[i].m_parent;
871 rot_from_world[i + 1] = rot_from_parent[i + 1] * rot_from_world[parent + 1];
873 fromParent.
m_rotMat = rot_from_parent[i + 1];
875 fromWorld.
m_rotMat = rot_from_world[i + 1];
876 fromParent.
transform(spatVel[parent + 1], spatVel[i + 1]);
884 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
888 spatVel[i + 1] += spatJointVel;
901 spatVel[i + 1].
cross(spatJointVel, spatCoriolisAcc[i]);
911 btVector3 linkAppliedForce = isConstraintPass ?
m_links[i].m_appliedConstraintForce :
m_links[i].m_appliedForce;
912 btVector3 linkAppliedTorque = isConstraintPass ?
m_links[i].m_appliedConstraintTorque :
m_links[i].m_appliedTorque;
914 zeroAccSpatFrc[i + 1].
setVector(-(rot_from_world[i + 1] * linkAppliedTorque), -(rot_from_world[i + 1] * linkAppliedForce));
919 b3Printf(
"stepVelocitiesMultiDof zeroAccSpatFrc[%d] linear:%f,%f,%f, angular:%f,%f,%f",
921 zeroAccSpatFrc[i+1].m_topVec[0],
922 zeroAccSpatFrc[i+1].m_topVec[1],
923 zeroAccSpatFrc[i+1].m_topVec[2],
925 zeroAccSpatFrc[i+1].m_bottomVec[0],
926 zeroAccSpatFrc[i+1].m_bottomVec[1],
927 zeroAccSpatFrc[i+1].m_bottomVec[2]);
932 btScalar linDampMult = 1., angDampMult = 1.;
933 zeroAccSpatFrc[i + 1].
addVector(angDampMult *
m_links[i].m_inertiaLocal * spatVel[i + 1].getAngular() * (DAMPING_K1_ANGULAR + DAMPING_K2_ANGULAR * spatVel[i + 1].getAngular().safeNorm()),
934 linDampMult *
m_links[i].m_mass * spatVel[i + 1].getLinear() * (DAMPING_K1_LINEAR + DAMPING_K2_LINEAR * spatVel[i + 1].getLinear().safeNorm()));
937 zeroAccSpatFrc[i + 1].
addAngular(spatVel[i + 1].getAngular().cross(
m_links[i].m_inertiaLocal * spatVel[i + 1].getAngular()));
939 if (!isConstraintPass)
940 zeroAccSpatFrc[i + 1].
addLinear(
m_links[i].m_mass * spatVel[i + 1].getAngular().cross(spatVel[i + 1].getLinear()));
963 0,
m_links[i].m_inertiaLocal[1], 0,
964 0, 0,
m_links[i].m_inertiaLocal[2]));
973 for (
int i = num_links - 1; i >= 0; --i)
977 const int parent =
m_links[i].m_parent;
978 fromParent.
m_rotMat = rot_from_parent[i + 1];
981 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
985 hDof = spatInertia[i + 1] *
m_links[i].m_axes[dof];
988 if (isConstraintPass) jointTorque = 0;
989 else jointTorque =
m_links[i].m_jointTorque[dof];
990 Y[
m_links[i].m_dofOffset + dof] = jointTorque -
m_links[i].m_axes[dof].dot(zeroAccSpatFrc[i + 1]) - spatCoriolisAcc[i].
dot(hDof);
993 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
996 for (
int dof2 = 0; dof2 <
m_links[i].m_dofCount; ++dof2)
999 D_row[dof2] =
m_links[i].m_axes[dof].dot(hDof2);
1004 switch (
m_links[i].m_jointType)
1011 invDi[0] = 1.0f / D[0];
1022 const btMatrix3x3 D3x3(D[0], D[1], D[2], D[3], D[4], D[5], D[6], D[7], D[8]);
1026 for (
int row = 0; row < 3; ++row)
1028 for (
int col = 0; col < 3; ++col)
1030 invDi[row * 3 + col] = invD3x3[row][col];
1042 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1044 spatForceVecTemps[dof].
setZero();
1046 for (
int dof2 = 0; dof2 <
m_links[i].m_dofCount; ++dof2)
1050 spatForceVecTemps[dof] += hDof2 * invDi[dof2 *
m_links[i].m_dofCount + dof];
1054 dyadTemp = spatInertia[i + 1];
1057 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1066 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1068 invD_times_Y[dof] = 0.f;
1070 for (
int dof2 = 0; dof2 <
m_links[i].m_dofCount; ++dof2)
1072 invD_times_Y[dof] += invDi[dof *
m_links[i].m_dofCount + dof2] * Y[
m_links[i].m_dofOffset + dof2];
1076 spatForceVecTemps[0] = zeroAccSpatFrc[i + 1] + spatInertia[i + 1] * spatCoriolisAcc[i];
1078 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1082 spatForceVecTemps[0] += hDof * invD_times_Y[dof];
1087 zeroAccSpatFrc[parent + 1] += spatForceVecTemps[1];
1109 spatAcc[0] = -result;
1113 for (
int i = 0; i < num_links; ++i)
1121 const int parent =
m_links[i].m_parent;
1122 fromParent.
m_rotMat = rot_from_parent[i + 1];
1125 fromParent.
transform(spatAcc[parent + 1], spatAcc[i + 1]);
1129 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1133 Y_minus_hT_a[dof] = Y[
m_links[i].m_dofOffset + dof] - spatAcc[i + 1].
dot(hDof);
1139 spatAcc[i + 1] += spatCoriolisAcc[i];
1141 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1142 spatAcc[i + 1] +=
m_links[i].m_axes[dof] * joint_accel[
m_links[i].m_dofOffset + dof];
1145 if (
m_links[i].m_jointFeedback)
1149 btVector3 angularBotVec = (spatInertia[i + 1] * spatAcc[i + 1] + zeroAccSpatFrc[i + 1]).m_bottomVec;
1150 btVector3 linearTopVec = (spatInertia[i + 1] * spatAcc[i + 1] + zeroAccSpatFrc[i + 1]).m_topVec;
1152 if (jointFeedbackInJointFrame)
1157 angularBotVec = angularBotVec - linearTopVec.
cross(
m_links[i].m_dVector);
1160 if (jointFeedbackInWorldSpace)
1162 if (isConstraintPass)
1164 m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec +=
m_links[i].m_cachedWorldTransform.getBasis() * angularBotVec;
1165 m_links[i].m_jointFeedback->m_reactionForces.m_topVec +=
m_links[i].m_cachedWorldTransform.getBasis() * linearTopVec;
1169 m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec =
m_links[i].m_cachedWorldTransform.getBasis() * angularBotVec;
1170 m_links[i].m_jointFeedback->m_reactionForces.m_topVec =
m_links[i].m_cachedWorldTransform.getBasis() * linearTopVec;
1175 if (isConstraintPass)
1177 m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec += angularBotVec;
1178 m_links[i].m_jointFeedback->m_reactionForces.m_topVec += linearTopVec;
1182 m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec = angularBotVec;
1183 m_links[i].m_jointFeedback->m_reactionForces.m_topVec = linearTopVec;
1191 output[0] = omegadot_out[0];
1192 output[1] = omegadot_out[1];
1193 output[2] = omegadot_out[2];
1195 const btVector3 vdot_out = rot_from_parent[0].
transpose() * (spatAcc[0].
getLinear() + spatVel[0].getAngular().cross(spatVel[0].getLinear()));
1220 if (!isConstraintPass)
1255 for (
int i = 0; i < num_links; ++i)
1257 const int parent =
m_links[i].m_parent;
1261 fromParent.
m_rotMat = rot_from_parent[i + 1];
1263 fromWorld.
m_rotMat = rot_from_world[i + 1];
1266 fromParent.
transform(spatVel[parent + 1], spatVel[i + 1]);
1274 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1278 spatVel[i + 1] += spatJointVel;
1323 for (
int i = 0; i < 6; i++)
1336 btMatrix3x3 invI_lower_right = (invI_upper_left).transpose();
1345 btVector3 vtop = invI_upper_left * rhs_top;
1347 tmp = invIupper_right * rhs_bot;
1349 btVector3 vbot = invI_lower_left * rhs_top;
1350 tmp = invI_lower_right * rhs_bot;
1352 result[0] = vtop[0];
1353 result[1] = vtop[1];
1354 result[2] = vtop[2];
1355 result[3] = vbot[0];
1356 result[4] = vbot[1];
1357 result[5] = vbot[2];
1401 btMatrix3x3 invI_lower_right = (invI_upper_left).transpose();
1424 for (
int row = 0; row < rowsA; row++)
1426 for (
int col = 0; col < colsB; col++)
1428 pC[row * colsB + col] = 0.f;
1429 for (
int inner = 0; inner < rowsB; inner++)
1431 pC[row * colsB + col] += pA[row * colsA + inner] * pB[col + inner * colsB];
1445 scratch_v.
resize(4 * num_links + 4);
1452 v_ptr += num_links * 2 + 2;
1461 v_ptr += num_links * 2 + 2;
1487 fromParent.
m_rotMat = rot_from_parent[0];
1490 for (
int i = 0; i < num_links; ++i)
1492 zeroAccSpatFrc[i + 1].
setZero();
1497 for (
int i = num_links - 1; i >= 0; --i)
1501 const int parent =
m_links[i].m_parent;
1502 fromParent.
m_rotMat = rot_from_parent[i + 1];
1505 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1507 Y[
m_links[i].m_dofOffset + dof] = force[6 +
m_links[i].m_dofOffset + dof] -
m_links[i].m_axes[dof].dot(zeroAccSpatFrc[i + 1]);
1510 btVector3 in_top, in_bottom, out_top, out_bottom;
1513 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1515 invD_times_Y[dof] = 0.f;
1517 for (
int dof2 = 0; dof2 <
m_links[i].m_dofCount; ++dof2)
1519 invD_times_Y[dof] += invDi[dof *
m_links[i].m_dofCount + dof2] * Y[
m_links[i].m_dofOffset + dof2];
1524 spatForceVecTemps[0] = zeroAccSpatFrc[i + 1];
1526 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1530 spatForceVecTemps[0] += hDof * invD_times_Y[dof];
1535 zeroAccSpatFrc[parent + 1] += spatForceVecTemps[1];
1551 spatAcc[0] = -result;
1555 for (
int i = 0; i < num_links; ++i)
1559 const int parent =
m_links[i].m_parent;
1560 fromParent.
m_rotMat = rot_from_parent[i + 1];
1563 fromParent.
transform(spatAcc[parent + 1], spatAcc[i + 1]);
1565 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1569 Y_minus_hT_a[dof] = Y[
m_links[i].m_dofOffset + dof] - spatAcc[i + 1].
dot(hDof);
1575 for (
int dof = 0; dof <
m_links[i].m_dofCount; ++dof)
1576 spatAcc[i + 1] +=
m_links[i].m_axes[dof] * joint_accel[
m_links[i].m_dofOffset + dof];
1582 output[0] = omegadot_out[0];
1583 output[1] = omegadot_out[1];
1584 output[2] = omegadot_out[2];
1612 for (
int i = 0; i < 3; ++i)
1618 pBasePos[0] += dt * pBaseVel[0];
1619 pBasePos[1] += dt * pBaseVel[1];
1620 pBasePos[2] += dt * pBaseVel[2];
1651 axis = angvel * (
btScalar(0.5) * dt - (dt * dt * dt) * (
btScalar(0.020833333333)) * fAngle * fAngle);
1656 axis = angvel * (
btSin(
btScalar(0.5) * fAngle * dt) / fAngle);
1677 for (
int i = 0; i < 4; ++i)
1686 baseQuat.
setValue(pBaseQuat[0], pBaseQuat[1], pBaseQuat[2], pBaseQuat[3]);
1688 baseOmega.
setValue(pBaseOmega[0], pBaseOmega[1], pBaseOmega[2]);
1689 pQuatUpdateFun(baseOmega, baseQuat,
true, dt);
1690 pBaseQuat[0] = baseQuat.
x();
1691 pBaseQuat[1] = baseQuat.
y();
1692 pBaseQuat[2] = baseQuat.
z();
1693 pBaseQuat[3] = baseQuat.
w();
1697 for (
int i = 0; i < num_links; ++i)
1700 pJointPos = &
m_links[i].m_jointPos_interpolate[0];
1702 if (
m_links[i].m_collider &&
m_links[i].m_collider->isStaticOrKinematic())
1704 switch (
m_links[i].m_jointType)
1709 pJointPos[0] =
m_links[i].m_jointPos[0];
1714 for (
int j = 0; j < 4; ++j)
1716 pJointPos[j] =
m_links[i].m_jointPos[j];
1722 for (
int j = 0; j < 3; ++j)
1724 pJointPos[j] =
m_links[i].m_jointPos[j];
1736 switch (
m_links[i].m_jointType)
1742 pJointPos[0] =
m_links[i].m_jointPos[0];
1744 pJointPos[0] += dt * jointVel;
1751 for (
int j = 0; j < 4; ++j)
1753 pJointPos[j] =
m_links[i].m_jointPos[j];
1757 jointVel.
setValue(pJointVel[0], pJointVel[1], pJointVel[2]);
1759 jointOri.
setValue(pJointPos[0], pJointPos[1], pJointPos[2], pJointPos[3]);
1760 pQuatUpdateFun(jointVel, jointOri,
false, dt);
1761 pJointPos[0] = jointOri.
x();
1762 pJointPos[1] = jointOri.
y();
1763 pJointPos[2] = jointOri.
z();
1764 pJointPos[3] = jointOri.
w();
1769 for (
int j = 0; j < 3; ++j)
1771 pJointPos[j] =
m_links[i].m_jointPos[j];
1777 pJointPos[1] +=
m_links[i].getAxisBottom(1).dot(no_q0_coors_qd1qd2) * dt;
1778 pJointPos[2] +=
m_links[i].getAxisBottom(2).dot(no_q0_coors_qd1qd2) * dt;
1787 m_links[i].updateInterpolationCacheMultiDof();
1803 pBasePos[0] += dt * pBaseVel[0];
1804 pBasePos[1] += dt * pBaseVel[1];
1805 pBasePos[2] += dt * pBaseVel[2];
1836 axis = angvel * (
btScalar(0.5) * dt - (dt * dt * dt) * (
btScalar(0.020833333333)) * fAngle * fAngle);
1841 axis = angvel * (
btSin(
btScalar(0.5) * fAngle * dt) / fAngle);
1863 baseQuat.
setValue(pBaseQuat[0], pBaseQuat[1], pBaseQuat[2], pBaseQuat[3]);
1865 baseOmega.
setValue(pBaseOmega[0], pBaseOmega[1], pBaseOmega[2]);
1866 pQuatUpdateFun(baseOmega, baseQuat,
true, dt);
1867 pBaseQuat[0] = baseQuat.
x();
1868 pBaseQuat[1] = baseQuat.
y();
1869 pBaseQuat[2] = baseQuat.
z();
1870 pBaseQuat[3] = baseQuat.
w();
1883 for (
int i = 0; i < num_links; ++i)
1885 if (!(
m_links[i].m_collider &&
m_links[i].m_collider->isStaticOrKinematic()))
1888 pJointPos= (pq ? pq : &
m_links[i].m_jointPos[0]);
1892 switch (
m_links[i].m_jointType)
1899 pJointPos[0] += dt * jointVel;
1906 jointVel.
setValue(pJointVel[0], pJointVel[1], pJointVel[2]);
1908 jointOri.
setValue(pJointPos[0], pJointPos[1], pJointPos[2], pJointPos[3]);
1909 pQuatUpdateFun(jointVel, jointOri,
false, dt);
1910 pJointPos[0] = jointOri.
x();
1911 pJointPos[1] = jointOri.
y();
1912 pJointPos[2] = jointOri.
z();
1913 pJointPos[3] = jointOri.
w();
1922 pJointPos[1] +=
m_links[i].getAxisBottom(1).dot(no_q0_coors_qd1qd2) * dt;
1923 pJointPos[2] +=
m_links[i].getAxisBottom(2).dot(no_q0_coors_qd1qd2) * dt;
1933 m_links[i].updateCacheMultiDof(pq);
1936 pq +=
m_links[i].m_posVarCount;
1954 scratch_v.
resize(3 * num_links + 3);
1955 scratch_m.
resize(num_links + 1);
1959 v_ptr += num_links + 1;
1961 v_ptr += num_links + 1;
1963 v_ptr += num_links + 1;
1972 int numLinksChildToRoot=0;
1976 links[numLinksChildToRoot++]=l;
1983 const btVector3 &normal_lin_world = normal_lin;
1984 const btVector3 &normal_ang_world = normal_ang;
1990 omega_coeffs_world = p_minus_com_world.
cross(normal_lin_world);
1991 jac[0] = omega_coeffs_world[0] + normal_ang_world[0];
1992 jac[1] = omega_coeffs_world[1] + normal_ang_world[1];
1993 jac[2] = omega_coeffs_world[2] + normal_ang_world[2];
1995 jac[3] = normal_lin_world[0];
1996 jac[4] = normal_lin_world[1];
1997 jac[5] = normal_lin_world[2];
2000 p_minus_com_local[0] = rot_from_world[0] * p_minus_com_world;
2001 n_local_lin[0] = rot_from_world[0] * normal_lin_world;
2002 n_local_ang[0] = rot_from_world[0] * normal_ang_world;
2011 if (num_links > 0 && link > -1)
2017 for (
int a = 0; a < numLinksChildToRoot; a++)
2019 int i = links[numLinksChildToRoot-1-a];
2021 const int parent =
m_links[i].m_parent;
2023 rot_from_world[i + 1] = mtx * rot_from_world[parent + 1];
2025 n_local_lin[i + 1] = mtx * n_local_lin[parent + 1];
2026 n_local_ang[i + 1] = mtx * n_local_ang[parent + 1];
2027 p_minus_com_local[i + 1] = mtx * p_minus_com_local[parent + 1] -
m_links[i].m_cachedRVector;
2030 switch (
m_links[i].m_jointType)
2034 results[
m_links[i].m_dofOffset] = n_local_lin[i + 1].dot(
m_links[i].getAxisTop(0).cross(p_minus_com_local[i + 1]) +
m_links[i].getAxisBottom(0));
2035 results[
m_links[i].m_dofOffset] += n_local_ang[i + 1].dot(
m_links[i].getAxisTop(0));
2040 results[
m_links[i].m_dofOffset] = n_local_lin[i + 1].dot(
m_links[i].getAxisBottom(0));
2045 results[
m_links[i].m_dofOffset + 0] = n_local_lin[i + 1].dot(
m_links[i].getAxisTop(0).cross(p_minus_com_local[i + 1]) +
m_links[i].getAxisBottom(0));
2046 results[
m_links[i].m_dofOffset + 1] = n_local_lin[i + 1].dot(
m_links[i].getAxisTop(1).cross(p_minus_com_local[i + 1]) +
m_links[i].getAxisBottom(1));
2047 results[
m_links[i].m_dofOffset + 2] = n_local_lin[i + 1].dot(
m_links[i].getAxisTop(2).cross(p_minus_com_local[i + 1]) +
m_links[i].getAxisBottom(2));
2049 results[
m_links[i].m_dofOffset + 0] += n_local_ang[i + 1].dot(
m_links[i].getAxisTop(0));
2050 results[
m_links[i].m_dofOffset + 1] += n_local_ang[i + 1].dot(
m_links[i].getAxisTop(1));
2051 results[
m_links[i].m_dofOffset + 2] += n_local_ang[i + 1].dot(
m_links[i].getAxisTop(2));
2057 results[
m_links[i].m_dofOffset + 0] = n_local_lin[i + 1].dot(
m_links[i].getAxisTop(0).cross(p_minus_com_local[i + 1]));
2058 results[
m_links[i].m_dofOffset + 1] = n_local_lin[i + 1].dot(
m_links[i].getAxisBottom(1));
2059 results[
m_links[i].m_dofOffset + 2] = n_local_lin[i + 1].dot(
m_links[i].getAxisBottom(2));
2073 for (
int dof = 0; dof <
m_links[link].m_dofCount; ++dof)
2075 jac[6 +
m_links[link].m_dofOffset + dof] = results[
m_links[link].m_dofOffset + dof];
2079 link =
m_links[link].m_parent;
2143 for (
int i = 0; i < num_links; ++i)
2150 world_to_local.
resize(nLinks + 1);
2151 local_origin.
resize(nLinks + 1);
2165 int index = link + 1;
2168 btScalar quat[4] = {-world_to_local[index].x(), -world_to_local[index].y(), -world_to_local[index].z(), world_to_local[index].w()};
2189 btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
2214 int index = link + 1;
2218 btScalar quat[4] = {-world_to_local[index].x(), -world_to_local[index].y(), -world_to_local[index].z(), world_to_local[index].w()};
2249 btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
2273 int index = link + 1;
2277 btScalar quat[4] = {-world_to_local[index].x(), -world_to_local[index].y(), -world_to_local[index].z(), world_to_local[index].w()};
2308 if (mbd->m_baseName)
2314 if (mbd->m_numLinks)
2317 int numElem = mbd->m_numLinks;
2320 for (
int i = 0; i < numElem; i++, memPtr++)
2355 for (
int posvar = 0; posvar < numPosVar; posvar++)
2363 if (memPtr->m_linkName)
2371 if (memPtr->m_jointName)
2383#ifdef BT_USE_DOUBLE_PRECISION
2384 memset(mbd->m_padding, 0,
sizeof(mbd->m_padding));
2395 btVector3 linearVelocity, angularVelocity;
2413 m_links[i].m_collider->setDynamicType(type);
2427 return m_links[i].m_collider->isStaticOrKinematic();
2441 return m_links[i].m_collider->isKinematic();
2449 while (link != -1) {
2452 link =
m_links[link].m_parent;
2460 while (link != -1) {
2463 link =
m_links[link].m_parent;
#define btCollisionObjectData
@ BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION
btMatrix3x3 outerProduct(const btVector3 &v0, const btVector3 &v1)
#define btMultiBodyDataName
#define btMultiBodyData
serialization data, don't change them if you are not familiar with the details of the serialization m...
#define btMultiBodyLinkData
#define btMultiBodyLinkDataName
btQuaternion inverse(const btQuaternion &q)
Return the inverse of a quaternion.
btVector3 quatRotate(const btQuaternion &rotation, const btVector3 &v)
bool gDisableDeactivation
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
btScalar btSin(btScalar x)
btScalar btCos(btScalar x)
void symmetricSpatialOuterProduct(const SpatialVectorType &a, const SpatialVectorType &b, btSymmetricSpatialDyad &out)
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
int size() const
return the number of elements in the array
void resize(int newsize, const T &fillData=T())
bool isStaticOrKinematicObject() const
void setCollisionFlags(int flags)
bool isStaticObject() const
void setWorldTransform(const btTransform &worldTrans)
bool isKinematicObject() const
int getCollisionFlags() const
void setInterpolationWorldTransform(const btTransform &trans)
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
btMatrix3x3 inverse() const
Return the inverse of the matrix.
btMatrix3x3 transpose() const
Return the transpose of the matrix.
btVector3 getColumn(int i) const
Get a column of the matrix as a vector.
void setValue(const btScalar &xx, const btScalar &xy, const btScalar &xz, const btScalar &yx, const btScalar &yy, const btScalar &yz, const btScalar &zx, const btScalar &zy, const btScalar &zz)
Set the values of the matrix explicitly (row major)
btScalar m_maxCoordinateVelocity
btTransform getInterpolateBaseWorldTransform() const
void setupPrismatic(int i, btScalar mass, const btVector3 &inertia, int parent, const btQuaternion &rotParentToThis, const btVector3 &jointAxis, const btVector3 &parentComToThisPivotOffset, const btVector3 &thisPivotToThisComOffset, bool disableParentCollision)
const btVector3 & getInterpolateBasePos() const
void setJointVelMultiDof(int i, const double *qdot)
const btVector3 & getLinkTorque(int i) const
void updateCollisionObjectInterpolationWorldTransforms(btAlignedObjectArray< btQuaternion > &world_to_local, btAlignedObjectArray< btVector3 > &local_origin)
btAlignedObjectArray< btMultibodyLink > m_links
btAlignedObjectArray< btMatrix3x3 > m_matrixBuf
btMultiBodyLinkCollider * m_baseCollider
btMatrix3x3 localFrameToWorld(int i, const btMatrix3x3 &local_frame) const
const btVector3 & getBasePos() const
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
bool isLinkAndAllAncestorsKinematic(const int i) const
btVector3 m_basePos_interpolate
btAlignedObjectArray< btVector3 > m_vectorBuf
const btQuaternion & getInterpolateParentToLocalRot(int i) const
btScalar m_maxAppliedImpulse
btVector3 worldDirToLocal(int i, const btVector3 &world_dir) const
btScalar getJointPos(int i) const
const btVector3 & getLinkInertia(int i) const
void setBaseDynamicType(int dynamicType)
btScalar * getJointPosMultiDof(int i)
btScalar m_angularDamping
void predictPositionsMultiDof(btScalar dt)
void * m_userObjectPointer
void setBaseVel(const btVector3 &vel)
btMatrix3x3 m_cachedInertiaLowerRight
void setBaseOmega(const btVector3 &omega)
void computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar dt, btAlignedObjectArray< btScalar > &scratch_r, btAlignedObjectArray< btVector3 > &scratch_v, btAlignedObjectArray< btMatrix3x3 > &scratch_m, bool isConstraintPass, bool jointFeedbackInWorldSpace, bool jointFeedbackInJointFrame)
void addLinkConstraintForce(int i, const btVector3 &f)
btAlignedObjectArray< btScalar > m_realBuf
btVector3 m_baseConstraintTorque
void stepPositionsMultiDof(btScalar dt, btScalar *pq=0, btScalar *pqd=0)
const btMultibodyLink & getLink(int index) const
const btVector3 & getRVector(int i) const
btVector3 getBaseOmega() const
void calcAccelerationDeltasMultiDof(const btScalar *force, btScalar *output, btAlignedObjectArray< btScalar > &scratch_r, btAlignedObjectArray< btVector3 > &scratch_v) const
stepVelocitiesMultiDof is deprecated, use computeAccelerationsArticulatedBodyAlgorithmMultiDof instea...
btVector3 worldPosToLocal(int i, const btVector3 &world_pos) const
void addLinkTorque(int i, const btVector3 &t)
void checkMotionAndSleepIfRequired(btScalar timestep)
btScalar * getJointTorqueMultiDof(int i)
btQuaternion m_baseQuat_interpolate
void solveImatrix(const btVector3 &rhs_top, const btVector3 &rhs_bot, btScalar result[6]) const
const btVector3 & getInterpolateRVector(int i) const
bool isBaseKinematic() const
btScalar getLinkMass(int i) const
bool m_useGlobalVelocities
void addLinkForce(int i, const btVector3 &f)
void addJointTorque(int i, btScalar Q)
btMatrix3x3 m_cachedInertiaLowerLeft
void mulMatrix(const btScalar *pA, const btScalar *pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const
void setInterpolateBaseWorldTransform(const btTransform &tr)
const btVector3 & getLinkForce(int i) const
int getParent(int link_num) const
void setJointPosMultiDof(int i, const double *q)
void updateCollisionObjectWorldTransforms(btAlignedObjectArray< btQuaternion > &world_to_local, btAlignedObjectArray< btVector3 > &local_origin)
void setJointVel(int i, btScalar qdot)
btScalar getJointTorque(int i) const
bool hasFixedBase() const
const btQuaternion & getInterpolateWorldToBaseRot() const
bool isLinkAndAllAncestorsStaticOrKinematic(const int i) const
void clearConstraintForces()
btMatrix3x3 m_cachedInertiaTopLeft
void addLinkConstraintTorque(int i, const btVector3 &t)
bool m_cachedInertiaValid
void setupSpherical(int i, btScalar mass, const btVector3 &inertia, int parent, const btQuaternion &rotParentToThis, const btVector3 &parentComToThisPivotOffset, const btVector3 &thisPivotToThisComOffset, bool disableParentCollision=false)
const btMultiBodyLinkCollider * getBaseCollider() const
void setJointPos(int i, btScalar q)
void setupPlanar(int i, btScalar mass, const btVector3 &inertia, int parent, const btQuaternion &rotParentToThis, const btVector3 &rotationAxis, const btVector3 &parentComToThisComOffset, bool disableParentCollision=false)
void setLinkDynamicType(const int i, int type)
static void spatialTransform(const btMatrix3x3 &rotation_matrix, const btVector3 &displacement, const btVector3 &top_in, const btVector3 &bottom_in, btVector3 &top_out, btVector3 &bottom_out)
void fillConstraintJacobianMultiDof(int link, const btVector3 &contact_point, const btVector3 &normal_ang, const btVector3 &normal_lin, btScalar *jac, btAlignedObjectArray< btScalar > &scratch_r, btAlignedObjectArray< btVector3 > &scratch_v, btAlignedObjectArray< btMatrix3x3 > &scratch_m) const
btTransform getBaseWorldTransform() const
btVector3 localPosToWorld(int i, const btVector3 &local_pos) const
bool isBaseStaticOrKinematic() const
void setupRevolute(int i, btScalar mass, const btVector3 &inertia, int parentIndex, const btQuaternion &rotParentToThis, const btVector3 &jointAxis, const btVector3 &parentComToThisPivotOffset, const btVector3 &thisPivotToThisComOffset, bool disableParentCollision=false)
bool m_kinematic_calculate_velocity
btMatrix3x3 m_cachedInertiaTopRight
btScalar getBaseMass() const
btAlignedObjectArray< btScalar > m_deltaV
void updateLinksDofOffsets()
virtual int calculateSerializeBufferSize() const
bool isLinkKinematic(const int i) const
void setupFixed(int i, btScalar mass, const btVector3 &inertia, int parent, const btQuaternion &rotParentToThis, const btVector3 &parentComToThisPivotOffset, const btVector3 &thisPivotToThisComOffset, bool deprecatedDisableParentCollision=true)
bool m_internalNeedsJointFeedback
the m_needsJointFeedback gets updated/computed during the stepVelocitiesMultiDof and it for internal ...
const btQuaternion & getParentToLocalRot(int i) const
btAlignedObjectArray< btScalar > m_splitV
const btVector3 & getBaseInertia() const
void addJointTorqueMultiDof(int i, int dof, btScalar Q)
const btQuaternion & getWorldToBaseRot() const
btVector3 m_baseConstraintForce
btVector3 localDirToWorld(int i, const btVector3 &local_dir) const
btScalar getJointVel(int i) const
bool isLinkStaticOrKinematic(const int i) const
void forwardKinematics(btAlignedObjectArray< btQuaternion > &world_to_local, btAlignedObjectArray< btVector3 > &local_origin)
void applyDeltaVeeMultiDof(const btScalar *delta_vee, btScalar multiplier)
const btVector3 getBaseVel() const
btScalar * getJointVelMultiDof(int i)
btMultiBody(int n_links, btScalar mass, const btVector3 &inertia, bool fixedBase, bool canSleep, bool deprecatedMultiDof=true)
void saveKinematicState(btScalar timeStep)
void compTreeLinkVelocities(btVector3 *omega, btVector3 *vel) const
void clearForcesAndTorques()
const btScalar & w() const
Return the w value.
const btScalar & z() const
Return the z value.
const btScalar & y() const
Return the y value.
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Set x,y,z and zero w.
const btScalar & x() const
Return the x value.
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
void serialize(struct btQuaternionData &dataOut) const
btQuaternion inverse() const
Return the inverse of this quaternion.
btQuaternion & normalize()
Normalize the quaternion Such that x^2 + y^2 + z^2 +w^2 = 1.
virtual btChunk * allocate(size_t size, int numElements)=0
virtual void * getUniquePointer(void *oldPtr)=0
virtual void serializeName(const char *ptr)=0
virtual const char * findNameForPointer(const void *ptr) const =0
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
btVector3 can be used to represent 3D points and vectors.
const btScalar & z() const
Return the z value.
btScalar length() const
Return the length of the vector.
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
btScalar dot(const btVector3 &v) const
Return the dot product.
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
btVector3 normalized() const
Return a normalized version of this vector.
const btScalar & x() const
Return the x value.
void serialize(struct btVector3Data &dataOut) const
const btScalar & y() const
Return the y value.
btQuaternion m_zeroRotParentToThis
class btMultiBodyLinkCollider * m_collider
btQuaternion m_cachedRotParentToThis
const btVector3 & getAxisTop(int dof) const
btScalar m_jointUpperLimit
const btVector3 & getAxisBottom(int dof) const
eFeatherstoneJointType m_jointType
btScalar m_jointLowerLimit
btSpatialMotionVector m_absFrameTotVelocity
btTransform m_cachedWorldTransform
btScalar m_jointMaxVelocity
btScalar m_jointTorque[6]
btSpatialMotionVector m_absFrameLocVelocity
btVector3 m_cachedRVector
These spatial algebra classes are used for btMultiBody, see BulletDynamics/Featherstone.
void addLinear(const btVector3 &linear)
void addVector(const btVector3 &angular, const btVector3 &linear)
const btVector3 & getAngular() const
const btVector3 & getLinear() const
void addAngular(const btVector3 &angular)
void setVector(const btVector3 &angular, const btVector3 &linear)
void setLinear(const btVector3 &linear)
const btVector3 & getLinear() const
void cross(const SpatialVectorType &b, SpatialVectorType &out) const
const btVector3 & getAngular() const
btScalar dot(const btSpatialForceVector &b) const
void setAngular(const btVector3 &angular)
void setVector(const btVector3 &angular, const btVector3 &linear)
btMatrix3x3 m_topRightMat
btMatrix3x3 m_bottomLeftMat
void setMatrix(const btMatrix3x3 &topLeftMat, const btMatrix3x3 &topRightMat, const btMatrix3x3 &bottomLeftMat)